package com.wzdigit.wms.wms.service.transfer;import com.alibaba.fastjson.JSON;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;import com.wzdigit.framework.Shift;import com.wzdigit.mes.basic.api.BasicDataItemDetailApi;import com.wzdigit.mes.basic.api.BasicSimpleCodeRuleApi;import com.wzdigit.mes.basic.dto.DataItemDetailDTO;import com.wzdigit.wms.basic.client.request.picktask.cancel.CancelPicktaskDtlRequest;import com.wzdigit.wms.basic.client.request.picktask.cancel.CancelPicktaskRequest;import com.wzdigit.wms.basic.client.request.transfer.WhsReq;import com.wzdigit.wms.basic.client.response.Result;import com.wzdigit.wms.basic.client.response.basic.LocationResponse;import com.wzdigit.wms.basic.client.response.picktask.cancel.PicktaskCancelResp;import com.wzdigit.wms.basic.client.response.transfer.*;import com.wzdigit.wms.basic.domain.asn.AsnDtl;import com.wzdigit.wms.basic.domain.asn.AsnDtlGoods;import com.wzdigit.wms.basic.domain.asn.AsnHeader;import com.wzdigit.wms.basic.domain.basic.Sku;import com.wzdigit.wms.basic.domain.basic.Warehouse;import com.wzdigit.wms.basic.domain.dtos.inventory.UpdateInventoryInputDto;import com.wzdigit.wms.basic.domain.dtos.transfer.TransferDtlDto;import com.wzdigit.wms.basic.domain.dtos.transfer.TransferDto;import com.wzdigit.wms.basic.domain.inventory.Goods;import com.wzdigit.wms.basic.domain.inventory.GoodsLog;import com.wzdigit.wms.basic.domain.inventory.InvLoc;import com.wzdigit.wms.basic.domain.inventory.InvTrans;import com.wzdigit.wms.basic.domain.mapping.CodeMapping;import com.wzdigit.wms.basic.domain.mid.IfPostback;import com.wzdigit.wms.basic.domain.order.TrsnDtl;import com.wzdigit.wms.basic.domain.order.TrsnDtlGoods;import com.wzdigit.wms.basic.domain.order.TrsnHeader;import com.wzdigit.wms.basic.domain.transfer.*;import com.wzdigit.wms.basic.enums.*;import com.wzdigit.wms.basic.enums.log.GoodsLogEnum;import com.wzdigit.wms.basic.enums.writeback.BackResultEnum;import com.wzdigit.wms.basic.enums.writeback.OtherSystemEnum;import com.wzdigit.wms.basic.enums.writeback.TopicEnum;import com.wzdigit.wms.basic.mapper.core.basic.SkuMapper;import com.wzdigit.wms.basic.mapper.core.basic.WarehouseMapper;import com.wzdigit.wms.basic.mapper.core.inventory.GoodsHisMapper;import com.wzdigit.wms.basic.mapper.core.inventory.GoodsLogMapper;import com.wzdigit.wms.basic.mapper.core.inventory.GoodsMapper;import com.wzdigit.wms.basic.mapper.core.order.AsnHeaderMapper;import com.wzdigit.wms.basic.mapper.core.transfer.*;import com.wzdigit.wms.basic.service.code.InventoryService;import com.wzdigit.wms.basic.util.HttpSessionUtil;import com.wzdigit.wms.wms.client.web.service.common.wms2sap.ZDT_Reserve;import com.wzdigit.wms.wms.client.web.service.wms2sap.transfer.ZDT_007_ReqRecordsHead;import com.wzdigit.wms.wms.client.web.service.wms2sap.transfer.ZDT_007_ReqRecordsHeadItems;import com.wzdigit.wms.common.entity.StatusCode;import com.wzdigit.wms.wms.service.basic.LocationService;import com.wzdigit.wms.wms.service.basic.SkuService;import com.wzdigit.wms.wms.service.basic.WarehouseService;import com.wzdigit.wms.wms.service.core.*;import com.wzdigit.wms.wms.service.core.outbound.PicktaskDtlGoodsService;import com.wzdigit.wms.wms.service.core.outbound.PicktaskDtlService;import com.wzdigit.wms.wms.service.core.outbound.PicktaskHeaderService;import com.wzdigit.wms.wms.service.core.transfer.TransferDtlGoodsService;import com.wzdigit.wms.wms.service.core.transfer.TransferDtlService;import com.wzdigit.wms.wms.service.core.transfer.TransferHeaderService;import com.wzdigit.wms.wms.service.mapping.CodeMappingNewService;import com.wzdigit.wms.wms.service.mid.IfPostbackService;import com.wzdigit.wms.wms.service.order.TurnWarehouseService;import com.wzdigit.wms.wms.service.outbound.PicktaskService;import lombok.extern.slf4j.Slf4j;import org.apache.dubbo.config.annotation.Reference;import org.springframework.beans.BeanUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Lazy;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.math.BigDecimal;import java.text.SimpleDateFormat;import java.util.*;import java.util.stream.Collectors;/** * 取消装运PDA Service * Created by zyf on 2021/5/27 15:32 */@Service@Slf4jpublic class GdnRemoveCtnrService {    @Autowired    private GdnRemoveCtnrMapper gdnRemoveCtnrMapper;    @Autowired    private GdnHeaderMapper gdnHeaderMapper;    @Autowired    private GdnDtlMapper gdnDtlMapper;    @Autowired    private SkuMapper skuMapper;    @Autowired    private GoodsHisMapper goodsHisMapper;    @Autowired    private GoodsMapper goodsMapper;    @Autowired    private AsnHeaderMapper asnHeaderMapper;    @Autowired    private WarehouseMapper warehouseMapper;    @Autowired    private TransferHeaderMapper transferHeaderMapper;    @Autowired    private TransferDtlMapper transferDtlMapper;    @Autowired    private TransferDtlGoodsMapper transferDtlGoodsMapper;    @Autowired    private CtnrLoadingMapper ctnrLoadingMapper;    @Autowired    private CtnrLoadingGoodsMapper ctnrLoadingGoodsMapper;    @Autowired    GoodsLogMapper goodsLogMapper;    @Autowired    private TrsnManagerService trsnManagerService;    @Autowired    private AsnManagerService asnManagerService;    @Autowired    private InventoryService inventoryService;    @Autowired    private TransferHeaderService transferHeaderService;    @Autowired    private TransferDtlService transferDtlService;    @Autowired    private TransferDtlGoodsService transferDtlGoodsService;    @Autowired    private GoodsService goodsService;    @Autowired    private TurnWarehouseService turnWarehouseService;    @Autowired    private TurnWshReceivedService turnWshReceivedService;    @Autowired    private WarehouseService warehouseService;    @Autowired    private CodeMappingNewService codeMappingNewService;    @Autowired    private SkuService skuService;    @Autowired    @Lazy    private IfPostbackService ifPostbackService;    @Autowired    @Lazy    private PicktaskService picktaskService;    @Lazy    @Autowired    PicktaskDtlGoodsService picktaskDtlGoodsService;    @Lazy    @Autowired    InvLocService invLocService;    @Lazy    @Autowired    PicktaskDtlService picktaskDtlService;    @Lazy    @Autowired    GdnCoreService gdnCoreService;    @Lazy    @Autowired    LocationService locationService;    @Lazy    @Autowired    InvZoneService invZoneService;    @Lazy    @Autowired    PicktaskHeaderService picktaskHeaderService;    @Value(value = "${default_owner.code}")    private String DEFAULT_OWNER;    @Value(value = "${default_owner.name}")    private String DEFAULT_OWNER_NAME;    @Reference(version = "${dubbo.consumers.basic.simple.code.rule.api:1.0.0}", check = false)    private BasicSimpleCodeRuleApi basicSimpleCodeRuleApi;    @Reference(version = "${dubbo.consumers.basic.data.item.detail.api:1.0.0}", check = false, timeout = 300000)    private BasicDataItemDetailApi dataItemDetailApi;    private static final String ANS_R97 = "ASN_R97";    final String TRSN_ORDER = "TRSN_ORDER";    //查询取消装运PDA主页    public Result<GdnRemoveCtnrResponse> searchGdnRemoveCtnr(String gdnNo){        Result result=new Result();        if (gdnNo==null){            Shift.fatal("请输入发货单号!");        }        //查询主页头部数据        GdnRemoveCtnrResponse gdnRemoveCtnrResponse = gdnRemoveCtnrMapper.selectOneByGoNo(gdnNo);        if (gdnRemoveCtnrResponse==null){            Shift.fatal("没有找到对应发货单号["+gdnNo+"]的信息");        }        //发货单状态=完成[4]或关闭[5]，则不允许取消装柜        if (gdnRemoveCtnrResponse.getHeaderStatus().equals(GdnHeaderStatusEnum.FINISH.code)){            Shift.fatal("发货单["+gdnNo+"]为"+"["+GdnHeaderStatusEnum.FINISH.enumName+                    "]状态，不能取消装柜！");        }        if (gdnRemoveCtnrResponse.getHeaderStatus().equals(GdnHeaderStatusEnum.CLOSE.code)){            Shift.fatal("发货单["+gdnNo+"]为"+"["+GdnHeaderStatusEnum.CLOSE.enumName+                    "]状态，不能取消装柜！");        }        //设置发货单表头状态        gdnRemoveCtnrResponse.setHeaderStatusString(GdnHeaderStatusEnum.getEnumByCode(                gdnRemoveCtnrResponse.getHeaderStatus()).enumName);        //设置发货单明细信息&需求数量&已装数量&取消数量        BigDecimal orderQtys=new BigDecimal(0);        BigDecimal shipQtys=new BigDecimal(0);        BigDecimal removeQtys=new BigDecimal(0);        List<GdnRemoveDtlResponse> gdnRemoveDtlResponses =                gdnRemoveCtnrMapper.selectDtlByHeader(gdnRemoveCtnrResponse.getGdnHeaderId());        if (gdnRemoveDtlResponses!=null&&gdnRemoveDtlResponses.size()>0){            gdnRemoveCtnrResponse.setGdnRemoveDtlList(gdnRemoveDtlResponses);            for (GdnRemoveDtlResponse gdnRemoveDtlRespons : gdnRemoveDtlResponses) {                orderQtys=orderQtys.add(gdnRemoveDtlRespons.getDtlOrderQty());                shipQtys=shipQtys.add(gdnRemoveDtlRespons.getDtlShipQty());                //设置发货单明细状态                gdnRemoveDtlRespons.setDtlStatusString(GdnDtlStatusEnum.                        getEnumByCode(gdnRemoveDtlRespons.getDtlStatus()).enumName                );            }        }        gdnRemoveCtnrResponse.setOrderQtys(orderQtys);        gdnRemoveCtnrResponse.setShipQtys(shipQtys);        gdnRemoveCtnrResponse.setRemoveQtys(removeQtys);        //设置已装SN信息&已装SN数量        List<GdnRemoveSnRespone> gdnRemoveSnRespones =                gdnRemoveCtnrMapper.selectSnByHeader(gdnRemoveCtnrResponse.getGdnHeaderId(), null);        if (gdnRemoveSnRespones!=null&&gdnRemoveSnRespones.size()>0){            gdnRemoveCtnrResponse.setGdnRemoveSnList(gdnRemoveSnRespones);            gdnRemoveCtnrResponse.setSnSize(gdnRemoveSnRespones.size());        }else {            gdnRemoveCtnrResponse.setSnSize(0);        }        result.setFlag(true);        result.setData(gdnRemoveCtnrResponse);        return result;    }    //整单取消    public Result<GdnRemoveSACResponse> removeAll(String gdnNo){        if (gdnNo==null){            Shift.fatal("请输入发货单号!");        }        Result result=new Result();        QueryWrapper<GdnHeader> gdnHeaderQueryWrapper=new QueryWrapper<>();        gdnHeaderQueryWrapper.eq("GDN_NO",gdnNo);        GdnHeader gdnHeader = gdnHeaderMapper.selectOne(gdnHeaderQueryWrapper);        BigDecimal gdnHeaderId=new BigDecimal(gdnHeader.getGdnHeaderId());        //查询显示用的取消SN列表信息        List<GdnRemoveSnRespone> showRemoveSn = gdnRemoveCtnrMapper.selectShowRemoveSn(gdnHeaderId, null);        //查询计算用的取消SN列表信息        List<GdnRemoveSnRespone> countRemoveSn = gdnRemoveCtnrMapper.selectCountRemoveSn(gdnHeaderId, null);        if (showRemoveSn==null){            Shift.fatal("发货单["+gdnNo+"]下没有已装SN[");        }        if (showRemoveSn.size()<=0){            Shift.fatal("发货单["+gdnNo+"]下没有已装SN");        }        GdnRemoveSACResponse data=new GdnRemoveSACResponse();        data.setShowRemoveSn(showRemoveSn);data.setCountRemoveSn(countRemoveSn);        result.setFlag(true);        result.setData(data);        return result;    }    //扫描SN取消    public Result<GdnRemoveSACResponse> removeOne(String gdnNo,String goodsSn){        if (gdnNo==null){            Shift.fatal("请输入发货单号!");        }        if (goodsSn==null){            Shift.fatal("请扫描要取消的SN!");        }        Result result=new Result();        QueryWrapper<GdnHeader> gdnHeaderQueryWrapper=new QueryWrapper<>();        gdnHeaderQueryWrapper.eq("GDN_NO",gdnNo);        GdnHeader gdnHeader = gdnHeaderMapper.selectOne(gdnHeaderQueryWrapper);        BigDecimal gdnHeaderId=new BigDecimal(gdnHeader.getGdnHeaderId());        //查询显示用的取消SN列表信息        List<GdnRemoveSnRespone> showRemoveSn = gdnRemoveCtnrMapper.selectShowRemoveSn(gdnHeaderId, goodsSn);        //查询计算用的取消SN列表信息        List<GdnRemoveSnRespone> countRemoveSn = gdnRemoveCtnrMapper.selectCountRemoveSn(gdnHeaderId, goodsSn);        if (showRemoveSn==null){            Shift.fatal("发货单["+gdnNo+"]下没有已装SN["+goodsSn+"]");        }        if (showRemoveSn.size()<=0){            Shift.fatal("发货单["+gdnNo+"]下没有已装SN["+goodsSn+"]");        }        GdnRemoveSACResponse data=new GdnRemoveSACResponse();        data.setShowRemoveSn(showRemoveSn);data.setCountRemoveSn(countRemoveSn);        result.setFlag(true);        result.setData(data);        return result;    }    /*提交取消装运：选择目的仓+取消的SN进行取消    步骤：    【备注：先从GOODS_HIS恢复数据到GOODS表,即3.2.2优先执行，    在入库单货物+库存凭证货物记录的ID为恢复后的ID】     * 1.根据发货单号查询发货单头     * 2.校验发货单状态=完成[4]或关闭[5]，则不允许取消装柜；如允许，查询要取消的SN信息     * 2.5 存在SN原仓库与目标仓库不一致且开关为关闭时，不允许取消装柜     * 3.根据SN信息的仓库分组     *      3.1根据不同仓库生成入库单+入库凭证单头，入库类型为R97[取消装柜]     *      3.2根据批次号+物料分组     *          3.2.1保存入库单明细+入库凭证明细     *          3.2.2将SN货品从历史表恢复到货物表，设置状态为4[已下架]     *          3.2.3保存入库明细货品+入库凭证明细货品     *          3.2.4设置库存信息，一条入库单明细对应一条库存信息     *          3.2.5增加库存     *          3.2.6更新入库单头、明细，入库凭证单头、明细状态     *      3.2.7 开关为开时，进行所有SN的取消拣货     *      3.3如果分组后的仓库与目的仓不一致，进行调拨，由于在3.2.4中已经恢复SN货品且设置状态，     *         因此调拨过程无需进行校验【备注：按仓库生成不同单头，按批次号+物编生成不同明细】     *          3.3.1生成调拨单头     *          3.3.2生成调拨单明细行，存入List集合，用于转仓接收     *          3.3.3保存调拨单货品     *          3.3.4更新库存     *          3.3.5记录操作日志     *          3.3.6批量修改调拨SN状态为已完成     *          3.3.7更新转仓单明细【实收数、状态】     *          3.3.8回传SAP【待定】     *          3.3.9更新【调拨单表头】状态     * 4.修改发货单表头、明细行、货物；修改装柜单头、明细行、货物等；明细行记录取消次数     *     */    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)    public Result removeSubmit(String gdnNo, Integer toWhsId, Boolean flag,                               String loginName, List<String> removeSnList,                               HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws Exception{        if (gdnNo==null){            Shift.fatal("请输入发货单号!");        }        if (removeSnList==null){            Shift.fatal("请扫描要取消SN!");        }        if (removeSnList.size()==0){            Shift.fatal("请扫描要取消SN!");        }        log.info("ZYF取消装运["+gdnNo+"]");        Result result=new Result();        //1.查询发货单头信息        QueryWrapper<GdnHeader> headerQuery=new QueryWrapper<>();        headerQuery.eq("GDN_NO",gdnNo);        //2.判断发货单状态        GdnHeader gdnHeader = gdnHeaderMapper.selectOne(headerQuery);        if (gdnHeader.getStatus().equals(GdnHeaderStatusEnum.FINISH.code)){            Shift.fatal("发货单["+gdnNo+"]为"+"["+GdnHeaderStatusEnum.FINISH.enumName+                    "]状态，不能取消装柜！");        }        if (gdnHeader.getStatus().equals(GdnHeaderStatusEnum.CLOSE.code)){            Shift.fatal("发货单["+gdnNo+"]为"+"["+GdnHeaderStatusEnum.CLOSE.enumName+                    "]状态，不能取消装柜！");        }        //找到发货单下gdnNo所有的SN，判断是否全部包括removeSnList，否则，报错        List<String> allGdnGoods = gdnRemoveCtnrMapper.selectAllGdnGoods(gdnHeader.getGdnHeaderId());        for (String goodsSn : removeSnList) {            if (!allGdnGoods.contains(goodsSn)){                Shift.fatal("发货单["+gdnNo+"]未包含条码为"+"["+goodsSn+                        "]的货品！");            }        }        //去除重复的SN        int snCount = removeSnList.size();        removeSnList=removeSnList.stream().distinct().collect(Collectors.toList());        if (removeSnList.size()!=snCount){            Shift.fatal("存在重复的SN!");        }        //3.2.2将SN从WMS_GOODS_HIS恢复到WMS_GOODS        recoverGoods(removeSnList,loginName);        List<GdnRemoveSnRespone> gdnRemoveSnRespones =                gdnRemoveCtnrMapper.selectSimpleRemoveSn(                        new BigDecimal(gdnHeader.getGdnHeaderId()), removeSnList);        for (GdnRemoveSnRespone gdnRemoveSnRespone : gdnRemoveSnRespones) {            List<String> goodsSn=new ArrayList<>();            goodsSn.add(gdnRemoveSnRespone.getSnGoodsSn());            gdnRemoveSnRespone.setSnWhsId(goodsHisMapper.selectGoodsWithWhsByHisSn(goodsSn).get(0).getWhsId());        }        //3.用仓库分组，不同仓库对应不同表头        Map<Integer, List<GdnRemoveSnRespone>> collectsByWhsId =                gdnRemoveSnRespones.stream().collect(Collectors.groupingBy(GdnRemoveSnRespone::getSnWhsId));        //如果需要调拨且开关为关闭，则不允许取消装运        for (Integer whsId : collectsByWhsId.keySet()){            if (!whsId.equals(toWhsId)&&flag.equals(false)){                Shift.fatal("存在异地卸柜SN，请打开【取消拣货】开关");            }        }        for (Integer whsId : collectsByWhsId.keySet()) {            int indexAsn=1;//用于生成入库单明细行号            int indexTransfer=1;//用于生成调拨单明细行号            List<GdnRemoveSnRespone> collectByWhsId = collectsByWhsId.get(whsId);            List<Integer> asnDtlIds=new ArrayList<>();//在入库完成后更新对应明细行状态            //3.1保存入库单单头&库存凭证单头            AsnHeader asnHeader = this.setAsnHeader(gdnHeader, whsId, loginName);            this.asnManagerService.getAsnHeaderService().addNewOne(asnHeader);            TrsnHeader trsnHeader = this.setTrsnHeader(asnHeader);            this.trsnManagerService.getTrsnHeaderMapper().insert(trsnHeader);            //3.2根据批次号+物流编码分组，对应不同明细行            Map<String, List<GdnRemoveSnRespone>> collectsByLotno = collectByWhsId.stream().collect(                    Collectors.groupingBy(t -> t.getSnLotno() + "#" +                            t.getSnSkuCode(), Collectors.toList()));            //3.2.1保存入库单明细&库存凭证明细            for (String lotnoAndSn : collectsByLotno.keySet()) {                List<GdnRemoveSnRespone> collectByLotno = collectsByLotno.get(lotnoAndSn);                List<String> removeSns=new ArrayList<>();                for (GdnRemoveSnRespone collect : collectByLotno) {                    removeSns.add(collect.getSnGoodsSn());                }                AsnDtl asnDtl = this.setAsnDtl(asnHeader,gdnNo,whsId,loginName,removeSns);                asnDtl.setAsnLineNo(""+indexAsn);indexAsn++;//设置库存明细行号                TrsnDtl trsnDtl = this.setTrsnDtl(asnHeader,asnDtl,trsnHeader);                this.asnManagerService.getAsnDtlService().addNewOne(asnDtl);                this.trsnManagerService.getTrsnDtlMapper().insert(trsnDtl);                asnDtlIds.add(asnDtl.getAsnDtlId());                //3.2.3保存入库货品信息&库存凭证货品信息                List<AsnDtlGoods> asnDtlGoods = this.setAsnDtlGoods(gdnNo, asnDtl, removeSns);                for (AsnDtlGoods asnDtlGood : asnDtlGoods) {                    this.asnManagerService.getAsnDtlGoodsService().addNewOne(asnDtlGood);                }                List<TrsnDtlGoods> trsnDtlGoods = this.setTrsnDtlGoods(trsnDtl, asnDtlGoods);                for (TrsnDtlGoods trsnDtlGood : trsnDtlGoods) {                    this.trsnManagerService.getTrsnDtlGoodsMapper().insert(trsnDtlGood);                }                //3.2.4设置库存信息                UpdateInventoryInputDto updateLocInventoryInputDto                        = this.setInventoryInputDto(asnHeader, asnDtl, gdnNo, removeSns);                InvTrans log = this.setInvTrans(asnHeader, asnDtl, trsnHeader, trsnDtl);                //3.2.5库存操作，SN原仓库库存增加                this.inventoryService.inventoryIn(updateLocInventoryInputDto,log);            }            //3.2.6更新入库单头、明细，入库凭证单头、明细状态            asnHeaderMapper.updateStatusById(asnHeader.getAsnHeaderId(),                    AsnHeaderStatusEnum.FINISH.code,loginName);            gdnRemoveCtnrMapper.updateAsnDtlStatus(asnDtlIds, AsnDtlStatusEnum.FINISH.getCode());            gdnRemoveCtnrMapper.updateTrasnfetDtlStatus(trsnHeader.getTrsnHeaderId(),                    TrsnHeaderStatusEnum.CMP.getCode());            //如果开关打开，进行取消拣货            if (flag.equals(true)){                CancelPicktaskRequest cancelPicktaskRequest=new CancelPicktaskRequest();                cancelPicktaskRequest.setCancelPicktaskFlag(false);                for (String lotnoAndSn : collectsByLotno.keySet()){                    List<GdnRemoveSnRespone> collectByLotno = collectsByLotno.get(lotnoAndSn);                    List<String> removeSns=new ArrayList<>();                    for (GdnRemoveSnRespone collect : collectByLotno) {                        String snGoodsSn = collect.getSnGoodsSn();                        List<PicktaskCancelResp> data = picktaskService.                                scanCancelPickSn(snGoodsSn, 0, servletRequest, servletResponse).getData();                        CancelPicktaskRequest requestDto=new CancelPicktaskRequest();                        List<CancelPicktaskDtlRequest> requestDtlDto=new ArrayList<>();                        for (PicktaskCancelResp resp : data) {                            CancelPicktaskDtlRequest requestDtl=new CancelPicktaskDtlRequest();                            requestDtl.setDtlId(resp.getPicktaskDtlId());                            requestDtl.setGoodsSn(resp.getGoodsSn());                            requestDtl.setScanMode(0);                            requestDtlDto.add(requestDtl);                        }                        requestDto.setCancelPicktaskDtlRequestList(requestDtlDto);                        requestDto.setCancelPicktaskFlag(false);                        picktaskService.cancelPicktaskPda(requestDto,servletRequest,servletResponse);                    }                }            }            //3.3如果货品原仓库与目的仓库不一致，从whsId调拨到toWhsId【转仓+转仓接收】            if (!whsId.equals(toWhsId)){                //----------转仓----------                WhsReq fmWhsReq = this.getWhsReq(whsId);                WhsReq toWhsReq = this.getWhsReq(toWhsId);                //3.3.1生成调拨单头                TransferHeader transferHeader = this.setTransferHeader(whsId, toWhsId, loginName,gdnNo);                transferHeader = transferHeaderService.addNewOne(transferHeader);                List<TransferDtl> transferDtlList=new ArrayList<>();//全部明细行                Map<Long,List<TransferDtlGoods>> transferDtlGoodsMap=new HashMap<>();//明细行对应调拨货品                for (String lotnoAndSn : collectsByLotno.keySet()) {                    List<GdnRemoveSnRespone> collectByLotno = collectsByLotno.get(lotnoAndSn);                    List<String> removeSns=new ArrayList<>();                    for (GdnRemoveSnRespone collect : collectByLotno) {                        removeSns.add(collect.getSnGoodsSn());                    }                    //3.3.2生成调拨单明细行，存入List集合，用于转仓接收                    TransferDtl transferDtl = this.setTransferDtl(transferHeader,gdnNo,removeSns,loginName);                    transferDtl.setTransferLineNo(""+indexTransfer);indexTransfer++;                    transferDtl = transferDtlService.addNewOne(transferDtl);                    transferDtlList.add(transferDtl);                    //3.3.3保存调拨单货品                    List<TransferDtlGoods> transferDtlGoods                            = this.setTransferDtlGoods(transferDtl, loginName, gdnNo, removeSns);                    transferDtlGoods=transferDtlGoodsService.addNewList(transferDtlGoods);                    transferDtlGoodsMap.put(transferDtl.getTransferDtlId(),transferDtlGoods);                }                //3.3.4更新库存                List<TransferDtlDto> transferDtlDtoList=new ArrayList<>();                for (TransferDtl transferDtl : transferDtlList) {                    TransferDtlDto transferDtlDto=new TransferDtlDto();                    transferDtlDto.setTransferDtl(transferDtl);                    transferDtlDto.setTransferDtlGoods(transferDtlGoodsMap.                            get(transferDtl.getTransferDtlId()));                    transferDtlDtoList.add(transferDtlDto);                }                TransferDto transferDto=new TransferDto();                transferDto.setTransferHeader(transferHeader);                transferDto.setTransferDtlDtoList(transferDtlDtoList);                turnWarehouseService.changeInventory(new Date(), loginName,                        fmWhsReq, toWhsReq, transferHeader.getTransferNo(), transferDto,                        transferHeader.getTransferType(), transferDtlDtoList, false);                //----------转仓完成，转仓接收----------                boolean falg = false;// 是否更新 【调拨单表头】 状态标识                Date transferDtlDate=new Date();                for (TransferDtl transferDtl : transferDtlList) {                    List<TransferDtlGoods> transferDtlGoods =                            transferDtlGoodsMap.get(transferDtl.getTransferDtlId());                    if (transferDtlGoods.size()>0){                        falg = true;                        Integer trsnHeaderStatus = null;// 库存交易凭证表头状态-->【进行中】                        Integer trsnDtlStatus = null;// 库存交易凭证明细状态-->【进行中】                        // 有效的转仓单货品清单ID集合                        List<Integer> dtlGoodsIds = transferDtlGoods.stream().                                map(TransferDtlGoods::getTransferGoodsId).collect(Collectors.toList());                        //3.3.6批量修改调拨SN状态为已完成                        transferDtlGoodsMapper.updateStatus(transferDtlDate, loginName, dtlGoodsIds);                        //3.3.7更新转仓单明细【实收数、状态】                        transferDtl.setCmpQty(transferDtl.getCmpQty() + transferDtlGoods.size());                        transferDtl.setModifyTime(transferDtlDate);                        transferDtl.setModifyUser(loginName);                        if (transferDtl.getOrderQty().equals(transferDtl.getCmpQty())) {                            transferDtl.setStatus(TransferDtlStatusEnum.CLOSE.code); 	// 关闭                            trsnHeaderStatus = TrsnHeaderStatusEnum.CMP.code;			// 完成                            trsnDtlStatus = TrsnDtlStatusEnum.CMP.code;					// 完成                        } else {                            transferDtl.setStatus(TransferDtlStatusEnum.DOING.code); 	// 进行中                            trsnHeaderStatus = TrsnHeaderStatusEnum.PRC.code;		 	// 进行中                            trsnDtlStatus = TrsnDtlStatusEnum.PRC.code;				 	// 进行中                        }                        transferDtlMapper.updateById(transferDtl);                        // 更新库存                        try{                            turnWshReceivedService.inventory(transferHeader, transferDtl,                                    transferDtlGoods, loginName, new Date(), trsnHeaderStatus, trsnDtlStatus);                        }catch (Exception e){                            e.printStackTrace();                        }                    }                }                // 3.3.9更新 【调拨单表头】 状态                if(falg) {                    QueryWrapper<TransferDtl> queryWrapper = new QueryWrapper<>();                    queryWrapper.eq("TRANSFER_HEADER_ID", transferHeader.getTransferHeaderId());                    queryWrapper.ge("STATUS", TransferDtlStatusEnum.CREATE.code);	// 创建                    queryWrapper.le("STATUS", TransferDtlStatusEnum.DOING.code);	// 进行中                    if(transferDtlMapper.selectCount(queryWrapper) == 0) {                        transferHeader.setStatus(TransferHeaderStatusEnum.CLOSE.code); // 完成                    } else {                        transferHeader.setStatus(TransferHeaderStatusEnum.DOING.code); 	// 进行中                    }                    transferHeader.setModifyTime(new Date());                    transferHeader.setModifyUser(loginName);                    transferHeader.setToBusinessMan(loginName);                    transferHeader.setTransferCmpTime(new Date());                    transferHeaderMapper.updateById(transferHeader);                }                IfPostback ifPostback = insertIfpostbackList(loginName, transferHeader, TransferTypeEnum.T09.code);                ifPostbackService.addOne(ifPostback);            }        }        /*  4. 修改发货单表头、明细行、货物；修改装柜单头、明细行、货物            1）更新发货单明细货品清单(wms_gdn_dtl_goods)将相应sn结合GDN_NO从该表删除			2）更新发货单明细(wms_gdn_dtl)ship_qty-=本次取消数量               若ship_qty=0,状态更新为5[待装运]按GDN_DTL_ID更新			3）更新装柜单货品清单(wms_ctnr_loading_goods)将相应sn从该表删除			4）更新装柜单(wms_ctnr_loading)cmp_qty-=本次取消数量,若cmp_qty=0,状态更新为1[新建]			5）更新发货单(wms_gdn_header)按GDN_HEADER_ID更新               若所有发货单明细.status=5，则更新发货单.status=1[新建]            6) 修改GOODS_SN对应仓库为目的仓         */        List<GdnDtlRemoveCount> gdnDtlSns = gdnRemoveCtnrMapper.selectDtlCount(gdnNo, removeSnList);        //要更新状态的明细和装柜单ID        List<BigDecimal> updateDtlIds=new ArrayList<>();        List<Integer> updateCtnrIds=new ArrayList<>();        Date changeStatusDate=new Date();        for (GdnDtlRemoveCount gdnDtlSn : gdnDtlSns) {            gdnRemoveCtnrMapper.deleteGdnDtlGoodSn(gdnDtlSn);            //ship_qty-1,un_loading_cnt+1            gdnRemoveCtnrMapper.updateGdnDtlNew(gdnDtlSn.getRemoveGdnDtlId(),loginName,new Date(),gdnDtlSn.getSnQty());            CtnrLoadingGoods ctnrLoadingGoods = gdnRemoveCtnrMapper.selectCtnrGoods(gdnDtlSn);            if (ctnrLoadingGoods==null){                Shift.fatal("发货单号["+gdnNo+"]与装柜数据不对应");            }            QueryWrapper<CtnrLoadingGoods> loadingGoodsQueryWrapper=new QueryWrapper<>();            loadingGoodsQueryWrapper.eq("CTNR_LOADING_GOODS_ID",ctnrLoadingGoods.getCtnrLoadingGoodsId());            ctnrLoadingGoodsMapper.delete(loadingGoodsQueryWrapper);            gdnRemoveCtnrMapper.updateCntrLoadingNew(ctnrLoadingGoods.getCtnrLoadingId(),loginName,new Date(),ctnrLoadingGoods.getQty());            updateDtlIds.add(gdnDtlSn.getRemoveGdnDtlId());            updateCtnrIds.add(ctnrLoadingGoods.getCtnrLoadingId());        }        //更新状态        List<BigDecimal> dtlIdsCollect = updateDtlIds.stream().distinct().collect(Collectors.toList());        List<Integer> ctnrIdsCollect = updateCtnrIds.stream().distinct().collect(Collectors.toList());        List<GdnDtl> gdnDtlCollect = gdnDtlMapper.                selectList(new QueryWrapper<GdnDtl>().in("GDN_DTL_ID", dtlIdsCollect));        for (GdnDtl gdnDtl : gdnDtlCollect) {            BigDecimal shipQty = gdnDtl.getShipQty();            if ((new  BigDecimal(0).compareTo(shipQty)==-1)&&                    (gdnDtl.getOrderQty().compareTo(shipQty)==1)){                gdnRemoveCtnrMapper.updateDtlStatusNew(gdnDtl.getGdnDtlId(),GdnDtlStatusEnum.LOADING.code);            }            if (shipQty.equals(BigDecimal.ZERO)){                BigDecimal pickQty = gdnDtl.getPickQty();                if (pickQty==null){                    pickQty=BigDecimal.ZERO;                }                if (pickQty.equals(BigDecimal.ZERO)){                    gdnRemoveCtnrMapper.updateDtlStatusNew(gdnDtl.getGdnDtlId(),GdnDtlStatusEnum.WAITPICK.code);                }else if(pickQty.equals(gdnDtl.getOrderQty())){                    gdnRemoveCtnrMapper.updateDtlStatusNew(gdnDtl.getGdnDtlId(),GdnDtlStatusEnum.WAITLOAD.code);                }                else {                    gdnRemoveCtnrMapper.updateDtlStatusNew(gdnDtl.getGdnDtlId(),GdnDtlStatusEnum.PICKING.code);                }            }            if (gdnDtl.getOrderQty().equals(BigDecimal.ZERO)&&                    gdnDtl.getShipQty().equals(BigDecimal.ZERO)&&                    gdnDtl.getPickQty().equals(BigDecimal.ZERO)){                gdnDtlMapper.delete(new QueryWrapper<GdnDtl>().eq("GDN_DTL_ID",gdnDtl.getGdnDtlId()));            }        }        List<CtnrLoading> ctnrCollect = ctnrLoadingMapper.selectList                (new QueryWrapper<CtnrLoading>().in("CTNR_LOADING_ID", ctnrIdsCollect));        for (CtnrLoading ctnrLoading : ctnrCollect) {            if (BigDecimal.ZERO.equals(ctnrLoading.getCmpQty())) {                gdnRemoveCtnrMapper.updateCtnrStatusNew(ctnrLoading.getCtnrLoadingId(), CtnrLoadingStatusEnum.CREATE.code);            } else if ((ctnrLoading.getCmpQty().compareTo(BigDecimal.ZERO) == 1) &&                    (ctnrLoading.getPlanQty().compareTo(ctnrLoading.getCmpQty()) == 1)) {                gdnRemoveCtnrMapper.updateCtnrStatusNew(ctnrLoading.getCtnrLoadingId(), CtnrLoadingStatusEnum.DOING.code);            }        }        //5)        Integer allDtlCounts = gdnRemoveCtnrMapper.                selectDtlCountByHeaderAndStatus(gdnHeader.getGdnHeaderId(), null);        Integer dtlCountsByStatus = gdnRemoveCtnrMapper.selectDtlCountByHeaderAndStatus                (gdnHeader.getGdnHeaderId(), GdnDtlStatusEnum.WAITLOAD.code);        if (allDtlCounts.equals(dtlCountsByStatus)){            gdnHeaderMapper.updateStatusByNo(GdnHeaderStatusEnum.DOING.code,gdnNo);        }        //6)修改GOODS_SN对应仓库为目的仓        Goods changeGoods=new Goods();        changeGoods.setWhsId(toWhsId);        changeGoods.setModifyTime(new Date());        changeGoods.setCreateUser(loginName);        goodsMapper.updateWhsIdBySns(changeGoods,removeSnList);//        Shift.fatal("////////////////");        result.setMessage("取消装柜成功");        return result;    }    private AsnHeader setAsnHeader(GdnHeader gdnHeader,Integer whsId,String loginName){        AsnHeader asnHeader=new AsnHeader();        Date localDate=new Date();        asnHeader.setAsnNo(this.basicSimpleCodeRuleApi.GenerateCode(ANS_R97));  //单号        asnHeader.setAsnType(AsnTypeEnum.R97.getCode());        asnHeader.setPriority(0);        asnHeader.setOwner(gdnHeader.getOwner());        asnHeader.setAsnCreateTime(localDate);        asnHeader.setExpectArriveTime1(localDate);        asnHeader.setFactory(gdnHeader.getFactory());        asnHeader.setToWhs(whsId);        asnHeader.setDataSource(gdnHeader.getGdnNo());        asnHeader.setReleaseStatus(BooleanEnum.TRUE.getCode());        asnHeader.setAsnPrintFlag(BooleanEnum.FALSE.getCode());        asnHeader.setQcStatus(QcStatusEnum.全部质检.getCode());  //判定结果        asnHeader.setSnScan(BooleanEnum.FALSE.getCode());        asnHeader.setComments("发货单["+gdnHeader.getGdnNo()+"]取消装柜");        asnHeader.setStatus(AsnHeaderStatusEnum.CREATE.code);        asnHeader.setCreateUser(loginName);        asnHeader.setModifyUser(loginName);        asnHeader.setCreateTime(localDate);        asnHeader.setModifyTime(localDate);        return asnHeader;    }    private AsnDtl setAsnDtl(AsnHeader asnHeader,String gdnNo,Integer whsId,                             String loginName,List<String> removeSns) {        GdnDtl gdnDtl = gdnRemoveCtnrMapper.                selectByGdnNoAndSn(gdnNo, removeSns.get(0)).get(0);        QueryWrapper<Goods> goodsQueryWrapper=new QueryWrapper<>();        goodsQueryWrapper.eq("GOODS_SN",removeSns.get(0));        Goods goods = goodsMapper.selectOne(goodsQueryWrapper);        Date localDate=new Date();        AsnDtl asnDtl = new AsnDtl();        asnDtl.setAsnHeaderId(asnHeader.getAsnHeaderId());        asnDtl.setAsnNo(asnHeader.getAsnNo());        asnDtl.setPoNo(gdnDtl.getPoNo());        asnDtl.setPoLineNo(gdnDtl.getPoLineNo());        asnDtl.setSkuId(gdnDtl.getSkuId());        asnDtl.setLotno(gdnDtl.getLotno());        asnDtl.setUnit(goods.getUnit());        asnDtl.setRcvTime(localDate);        asnDtl.setWhsId(whsId);        asnDtl.setQcStatus(gdnDtl.getQaStatus());        asnDtl.setQaStatus(gdnDtl.getQaStatus());        asnDtl.setLotAttr1(gdnDtl.getPoNo());        asnDtl.setLotAttr2(gdnDtl.getSoNo());        asnDtl.setLotAttr3(gdnDtl.getSoLineNo());        asnDtl.setDataSource(asnHeader.getDataSource());        asnDtl.setSourceNo(gdnNo);        asnDtl.setSoNo(gdnDtl.getSoNo());        asnDtl.setSoLineNo(gdnDtl.getSoLineNo());        asnDtl.setComments(asnDtl.getComments());        asnDtl.setStatus(AsnDtlStatusEnum.CREATE.getCode());        asnDtl.setInvAttr(gdnDtl.getInvAttr());//设置库存性质，用于增加库存        asnDtl.setCreateUser(loginName);        asnDtl.setModifyUser(loginName);        asnDtl.setCreateTime(localDate);        asnDtl.setModifyTime(localDate);        QueryWrapper<Sku> queryWrapper=new QueryWrapper<>();        queryWrapper.eq("SKU_ID",gdnDtl.getSkuId());        Sku sku = skuMapper.selectOne(queryWrapper);        asnDtl.setSkuDesc(sku.getDescCn());        asnDtl.setSkuDescEn(sku.getDescEn());        //收货数量即要取消的数量        BigDecimal dtlRecvQty = gdnRemoveCtnrMapper.selectRemoveQtysBySns(gdnNo, removeSns);        asnDtl.setOrderQty(dtlRecvQty);        asnDtl.setOrderQtyEa(dtlRecvQty);        asnDtl.setRcvQty(dtlRecvQty);        asnDtl.setRcvQtyEa(dtlRecvQty);        return asnDtl;    }    private List<AsnDtlGoods> setAsnDtlGoods(String gdnNo,AsnDtl asnDtl,List<String> removeSns){        Date localDate=new Date();        List<AsnDtlGoods> asnDtlGoods=new ArrayList<>();        List<GdnDtlGoods> gdnDtlGoods = gdnRemoveCtnrMapper.selectDtlGoodsByNoAndSn(gdnNo,removeSns);        for (GdnDtlGoods gdnDtlGood : gdnDtlGoods) {            AsnDtlGoods asnDtlGood=new AsnDtlGoods();            asnDtlGood.setQty(gdnDtlGood.getQty());            asnDtlGood.setGoodsSn(gdnDtlGood.getGoodsSn());            asnDtlGood.setAsnDtlId(asnDtl.getAsnDtlId());            asnDtlGood.setGoodsId(goodsMapper.selectBySn(gdnDtlGood.getGoodsSn()).getGoodsId());            asnDtlGood.setQaStatus(gdnDtlGood.getQaStatus());            asnDtlGood.setComments("发货单["+gdnNo+"]取消装柜");            asnDtlGood.setStatus(AsnDtlGoodsStatusEnum.HAS_RECEIVE.getCode());            asnDtlGood.setCreateUser(asnDtl.getCreateUser());            asnDtlGood.setModifyUser(asnDtl.getCreateUser());            asnDtlGood.setCreateTime(localDate);            asnDtlGood.setModifyTime(localDate);            asnDtlGoods.add(asnDtlGood);        }        return asnDtlGoods;    }    private TrsnHeader setTrsnHeader(AsnHeader asnHeader) {        Date localDate=new Date();        TrsnHeader item = new TrsnHeader();        item.setNoteNo(basicSimpleCodeRuleApi.GenerateCode(TRSN_ORDER));        item.setNoteType(TrsnNoteTypeEnum.IN_STORAGE.getCode()); //凭证类型        item.setOwner(asnHeader.getOwner());        item.setFactory(asnHeader.getFactory());        item.setWhsId(asnHeader.getToWhs());        item.setFmDoc(asnHeader.getAsnNo()); //来源单据        item.setStatus(TrsnHeaderStatusEnum.CRT.getCode());        item.setCreateTime(localDate);        item.setModifyTime(localDate);        item.setDocRef1(asnHeader.getAsnRef1());        item.setDocRef2(asnHeader.getAsnRef2());        item.setDocRef3(asnHeader.getAsnRef3());        item.setDocRef4(asnHeader.getAsnRef4());        item.setDocRef5(asnHeader.getAsnRef5());        item.setModifyUser(asnHeader.getModifyUser());        item.setCreateUser(asnHeader.getModifyUser());        return item;    }    private TrsnDtl setTrsnDtl(AsnHeader asnHeader, AsnDtl asnDtl,TrsnHeader trsnHeader) {        TrsnDtl item = new TrsnDtl();        Date localDate=new Date();        item.setTrsnHeaderId(trsnHeader.getTrsnHeaderId());        item.setNoteNo(trsnHeader.getNoteNo());        item.setNoteLineNo(asnDtl.getAsnLineNo());        item.setInvUpdateFlag(TrsnDtlInvUpdateFlagEnum.IN.getCode());        item.setFmDoc(asnDtl.getAsnNo());        item.setFmDocLine(asnDtl.getAsnLineNo());        item.setSkuId(asnDtl.getSkuId());        item.setQty(asnDtl.getRcvQty());        item.setUnit(asnDtl.getUnit());        item.setQaStatus(asnDtl.getQaStatus());        item.setInvAttr(asnDtl.getInvAttr());        item.setLotAttr1(asnDtl.getLotAttr1());        item.setLotAttr2(asnDtl.getLotAttr2());        item.setLotAttr3(asnDtl.getLotAttr3());        item.setLotAttr4(asnDtl.getLotAttr4());        item.setLotAttr5(asnDtl.getLotAttr5());        item.setLotAttr6(asnDtl.getLotAttr6());        item.setLotAttr7(asnDtl.getLotAttr7());        item.setLotAttr8(asnDtl.getLotAttr8());        item.setLotAttr9(asnDtl.getLotAttr9());        item.setLotAttr10(asnDtl.getLotAttr10());        item.setLotAttr11(asnDtl.getLotAttr11());        item.setLotAttr12(asnDtl.getLotAttr12());        item.setStatus(TrsnDtlStatusEnum.CMP.getCode());        item.setCreateTime(localDate);        item.setModifyTime(localDate);        item.setModifyUser(asnHeader.getModifyUser());        item.setCreateUser(asnHeader.getModifyUser());        return item;    }    private List<TrsnDtlGoods> setTrsnDtlGoods(TrsnDtl trsnDtl, List<AsnDtlGoods> asnDtlGoods) {        Date localDate=new Date();        List<TrsnDtlGoods> list = new ArrayList<>();        for (AsnDtlGoods goods : asnDtlGoods) {            TrsnDtlGoods item = new TrsnDtlGoods();            item.setTrsnDtlId(trsnDtl.getTrsnDtlId());            item.setGoodsId(goods.getGoodsId());            item.setGoodsSn(goods.getGoodsSn());            item.setQaStatus(goods.getQaStatus());            item.setQty(goods.getQty());            item.setComments(goods.getComments());            item.setStatus(TrsnDtlGoodsStatusEnum.RECEIVED.getCode());            item.setCreateUser(trsnDtl.getModifyUser());            item.setModifyUser(trsnDtl.getModifyUser());            item.setCreateTime(localDate);            item.setModifyTime(localDate);            list.add(item);        }        return list;    }    private UpdateInventoryInputDto setInventoryInputDto(            AsnHeader asnHeader,AsnDtl asnDtl,String gdnNo,List<String> removeSns){        UpdateInventoryInputDto inventoryInputDto = new UpdateInventoryInputDto();        List<Goods> goodsList = goodsHisMapper.selectGoodsWithWhsByHisSn(removeSns);        inventoryInputDto.setWhsId(goodsList.get(0).getWhsId());        inventoryInputDto.setOwner(goodsList.get(0).getOwner());        inventoryInputDto.setSkuId(goodsList.get(0).getSkuId());        inventoryInputDto.setFactory(goodsList.get(0).getFactory());        inventoryInputDto.setVendorId(goodsList.get(0).getVendorId());        inventoryInputDto.setLotNo(goodsList.get(0).getLotno());        inventoryInputDto.setInvAttr(goodsList.get(0).getInvAttr());        inventoryInputDto.setQaStatus(goodsList.get(0).getQaStatus());        inventoryInputDto.setUnit(goodsList.get(0).getUnit());        inventoryInputDto.setOperator(goodsList.get(0).getModifyUser());        BigDecimal qtys = gdnRemoveCtnrMapper.selectRemoveQtysBySns(gdnNo, removeSns);        inventoryInputDto.setQty(qtys);        inventoryInputDto.setAlocQty(qtys);        return inventoryInputDto;    }    private InvTrans setInvTrans(AsnHeader asnHeader,AsnDtl asnDtl,                                 TrsnHeader trsnHeader,TrsnDtl trsnDtl){        Date localDate=new Date();        InvTrans log = new InvTrans();        log.setOpCode(OpCodeEnum.RECEIVE.getCode());        log.setDocType(asnHeader.getAsnType());        log.setDocNo(asnDtl.getAsnNo());        log.setDocLineNo(asnDtl.getAsnLineNo());        log.setTrsnNo(trsnHeader.getNoteNo());        log.setTrsnLineNo(trsnDtl.getNoteLineNo());        log.setStatus(InvTransStatusEnum.FINISHED.getCode());        log.setTransTime(localDate);        log.setOperator(asnDtl.getModifyUser());        log.setTransQty(asnDtl.getRcvQty());        log.setCreateTime(localDate);        log.setModifyTime(localDate);        log.setCreateUser(asnDtl.getModifyUser());        log.setModifyUser(asnDtl.getModifyUser());        return log;    }    //从历史表查询货品信息恢复到货品表    private void recoverGoods(List<String> goodsSns,String loginName){        Date localDate=new Date();        //历史表不会删除SN，因此取ID最大的一条        List<Goods> allGoods = goodsHisMapper.selectGoodsWithWhsByHisSn(goodsSns);        //记录操作日志        for (Goods allGood : allGoods) {            GoodsLog goodsLog = new GoodsLog();            goodsLog.setCreateTime(new Date());            goodsLog.setCreateUser(loginName);            goodsLog.setGoodsSn(allGood.getGoodsSn());            goodsLog.setOpCode("ContainerUnLoad");            goodsLog.setReason("取消装柜");            goodsLog.setOperator(loginName);            String goodsOriginalJson = JSON.toJSONString(allGood);//原先的json            allGood.setStatus(GoodsStatusEnum.HAS_DOWN.code);            allGood.setModifyUser(loginName);            allGood.setModifyTime(localDate);            String goodsJson=JSON.toJSONString(allGood);//新的json            String jsonString = "未更新的:" + goodsOriginalJson + ",更新的:" + goodsJson;            goodsLog.setUpdateContent(jsonString);            goodsService.insertGoodsLog(goodsLog);        }        List<String> allGoodsSn=new ArrayList<>();        for (Goods good : allGoods) {            allGoodsSn.add(good.getGoodsSn());        }        List<Goods> exitGoods = goodsMapper.selectBySNs(allGoodsSn);        List<Goods> noExitGoods = allGoods.stream().filter(b -> exitGoods.stream().                map(Goods::getGoodsSn).noneMatch(id -> Objects.equals(b.getGoodsSn(), id))).collect(Collectors.toList());        //货品表已存在SN则更新        if (exitGoods!=null&&exitGoods.size()>0){            for (Goods exitGood : exitGoods) {                exitGood.setStatus(GoodsStatusEnum.HAS_DOWN.code);                exitGood.setModifyUser(loginName);                exitGood.setModifyTime(localDate);                exitGood.setPkgId(null);                gdnRemoveCtnrMapper.updateGoodsBySn(exitGood);            }        }        //货品表不存在SN则新增        if (noExitGoods!=null&&noExitGoods.size()>0){            for (Goods noExitGood : noExitGoods) {                noExitGood.setStatus(GoodsStatusEnum.HAS_DOWN.code);                noExitGood.setCreateUser(loginName);                noExitGood.setCreateTime(localDate);                noExitGood.setModifyUser(loginName);                noExitGood.setModifyTime(localDate);                noExitGood.setPkgId(null);                goodsMapper.insert(noExitGood);            }        }    }    private WhsReq getWhsReq(Integer whsId){        WhsReq whsReq=new WhsReq();        QueryWrapper<Warehouse> queryWrapper=new QueryWrapper<>();        queryWrapper.eq("WHS_ID",whsId);        Warehouse warehouse = warehouseMapper.selectOne(queryWrapper);        whsReq.setWhsId(warehouse.getWhsId());        whsReq.setWhsCode(warehouse.getWhsCode());        whsReq.setWhsName(warehouse.getWhsName());        whsReq.setWhsType(warehouse.getWhsType());        return whsReq;    }    private TransferHeader setTransferHeader(Integer fmWhdId,Integer toWhsId,String loginName,String gdnNo){        Date localDate=new Date();        TransferHeader transferHeader = new TransferHeader();        transferHeader.setTransferNo(basicSimpleCodeRuleApi.GenerateCode("T09"));        transferHeader.setTransferType(TransferTypeEnum.T09.code);//调拨单类型        transferHeader.setFmWhs(fmWhdId);//来源仓库        transferHeader.setToWhs(toWhsId);//目的仓库        transferHeader.setDeliveryVehicleNo("取消装柜");//车牌号        transferHeader.setDeliveryVehicleType(0);//车型        transferHeader.setDriver("取消装柜");//司机        transferHeader.setFmBusinessMan(loginName);//来源方业务员        transferHeader.setTransferCreateTime(localDate);//调拨单创建时间        transferHeader.setTransferCmpTime(localDate);        transferHeader.setStatus(TransferHeaderStatusEnum.CREATE.getCode());        transferHeader.setCreateTime(localDate);        transferHeader.setCreateUser(loginName);        transferHeader.setSourceNo(gdnNo);        transferHeader.setTransferCreateUser(loginName);        return transferHeader;    }    private TransferDtl setTransferDtl(TransferHeader transferHeader,String gdnNo,List<String> removeSns,                                       String loginName){        TransferDtl transferDtl=new TransferDtl();        Goods goods = goodsService.selectBySn(removeSns.get(0));        //默认货主        DataItemDetailDTO dataItem = dataItemDetailApi.getDataItemDetailByPCodeAndName(DEFAULT_OWNER, DEFAULT_OWNER_NAME);        Integer customerId = (dataItem == null || dataItem.getItemValue() == null ? 0 : Integer.parseInt(dataItem.getItemValue()));        Date localDate=new Date();        transferDtl.setTransferNo(transferHeader.getTransferNo());        transferDtl.setTransferHeaderId(transferHeader.getTransferHeaderId());        transferDtl.setSourceNo(gdnNo).setFmSku(goods.getSkuId()).setFmOwner(customerId).setFmFactory(goods.getFactory());        transferDtl.setFmQaStatus(goods.getQaStatus());        transferDtl.setFmLotno(goods.getLotno());        transferDtl.setToSku(goods.getSkuId());        transferDtl.setToOwner(goods.getOwner());        transferDtl.setFmOwner(goods.getOwner());        transferDtl.setToFactory(goods.getFactory());        transferDtl.setToQaStatus(goods.getQaStatus());        transferDtl.setToLotno(goods.getLotno());        transferDtl.setUnit(goods.getUnit());        transferDtl.setOrderQty(gdnRemoveCtnrMapper.selectRemoveQtysBySn(gdnNo,removeSns));//订单数量        transferDtl.setTransitQty(0).setCmpQty(0);//在途数量和完成数量        transferDtl.setUdf1(goods.getPoNo());        transferDtl.setStatus(TransferDtlStatusEnum.CREATE.getCode());//新建        transferDtl.setCreateUser(loginName);        transferDtl.setCreateTime(localDate);        transferDtl.setFmPo(goods.getPoNo());        transferDtl.setToPo(goods.getPoNo());        transferDtl.setFmSoNo(goods.getSoNo());        transferDtl.setToSoNo(goods.getSoNo());        transferDtl.setFmSoLineNo(goods.getSoItem());        transferDtl.setToSoLineNo(goods.getSoItem());        transferDtl.setFmLotAttr1(goods.getPoNo());        transferDtl.setToLotAttr1(goods.getPoNo());        transferDtl.setFmLotAttr2(goods.getSoNo());        transferDtl.setToLotAttr2(goods.getSoNo());        transferDtl.setFmLotAttr3(goods.getSoItem());        transferDtl.setToLotAttr3(goods.getSoItem());        transferDtl.setTransferTime(localDate);        transferDtl.setReturnTime(localDate);        return transferDtl;    }    private List<TransferDtlGoods> setTransferDtlGoods(TransferDtl transferDtl,String loginName,                                                       String gdnNo,List<String> removeSns){        Date localDate=new Date();        List<TransferDtlGoods> transferDtlGoodsList=new ArrayList<>();        List<GdnDtlGoods> gdnDtlGoods = gdnRemoveCtnrMapper.selectDtlGoodsByNoAndSn(gdnNo,removeSns);        for (GdnDtlGoods gdnDtlGood : gdnDtlGoods) {            TransferDtlGoods transferDtlGoods=new TransferDtlGoods();            transferDtlGoods.setTransferDtlId(transferDtl.getTransferDtlId());            transferDtlGoods.setGoodsId(goodsMapper.selectBySn(gdnDtlGood.getGoodsSn()).getGoodsId());            transferDtlGoods.setQaStatus(gdnDtlGood.getQaStatus());            transferDtlGoods.setQty(gdnDtlGood.getQty());            transferDtlGoods.setGoodsSn(gdnDtlGood.getGoodsSn());            transferDtlGoods.setComments("发货单["+gdnNo+"]取消装柜");            transferDtlGoods.setStatus(TransferDtlGoodStatusEnum.WAIT_RECEIVE.code);            transferDtlGoods.setCreateTime(localDate);            transferDtlGoods.setCreateUser(loginName);            transferDtlGoodsList.add(transferDtlGoods);        }        return transferDtlGoodsList;    }    //调拨单回传SAP    public IfPostback insertIfpostbackList(String loginName, TransferHeader transferHeader, String transferType) {        IfPostback ifPostback = new IfPostback();        ifPostback.setDestSystem(OtherSystemEnum.SYSYTEM_SAP.getEnumName());        ifPostback.setPostbackTopic(TopicEnum.TOPIC_SAP_TRANSFER.getEnumName());        ifPostback.setPostbackNo(transferHeader.getTransferNo());        ifPostback.setPostbackType(transferType);        ifPostback.setPostbackSourceNo(transferHeader.getSourceNo());        List<TransferDtl> transferDtlList = transferDtlService.getByHeaderId(transferHeader.getTransferHeaderId());        Integer fmWhs = transferHeader.getFmWhs();//单头源仓库        Integer toWhs = transferHeader.getToWhs();//单头目的仓        ZDT_007_ReqRecordsHead head = new ZDT_007_ReqRecordsHead();        if (transferType.equals(TransferTypeEnum.T03.getCode())) {            //组织间调拨            head.setZCJLX("2");//创建类型            head.setBWART("");//移动类型（创建类型2无需填）        } else if (transferType.equals(TransferTypeEnum.T04.getCode())) {            //销售订单调拨            head.setZCJLX("4");//创建类型            String erpMoveType = transferHeader.getErpMoveType();            if (erpMoveType == null) {                erpMoveType = "";                log.warn("ERP_MOVE_TYPE字段的值为NULL");            }            head.setBWART(erpMoveType);//移动类型（创建类型2无需填）        } else if (transferType.equals(TransferTypeEnum.T05.getCode()) || transferType.equals(TransferTypeEnum.T06.getCode())||transferType.equals(TransferTypeEnum.T09.getCode())) {            //借机||还机            head.setZCJLX("1");//创建类型            head.setBWART("311");//移动类型（创建类型2 无需填）        }        head.setZGLJYD(transferHeader.getTransferNo());//调拨单号        if (transferHeader.getPurchsingOrg() != null) {            head.setEKORG(transferHeader.getPurchsingOrg());//采购组织（创建类型2必填）        } else {            head.setEKORG("");//采购组织（创建类型2必填）        }        if (transferHeader.getCompanyCode() != null) {            head.setBUKRS(transferHeader.getCompanyCode());//公司代码（创建类型2必填）        } else {            head.setBUKRS("");//公司代码（创建类型2必填）        }        head.setZCJR(loginName);//创建人        head.setZCJRZH(loginName);//创建人账号        head.setZCJRQ(getDateStr());//创建日期        head.setZCJSJ(getTimeStr());//创建时间        ZDT_Reserve reserve = new ZDT_Reserve();        reserve.setRsv1("");        reserve.setRsv2("");        reserve.setRsv3("");        reserve.setRsv4("");        reserve.setRsv5("");        head.setRSV(reserve);        List<ZDT_007_ReqRecordsHeadItems> items = new ArrayList<>();        //设置ITEMS        if(transferType.equals(TransferTypeEnum.T05.getCode()) || transferType.equals(TransferTypeEnum.T06.getCode())||transferType.equals(TransferTypeEnum.T09.getCode())){            createT05AndT06Items(transferDtlList, fmWhs, toWhs, head, items);        } else {            createT03AndT04Items(transferDtlList, fmWhs, toWhs, head, items);        }        ZDT_007_ReqRecordsHeadItems[] recordsHeadItemsArr = items.toArray(new ZDT_007_ReqRecordsHeadItems[items.size()]);        head.setItems(recordsHeadItemsArr);        List<ZDT_007_ReqRecordsHead> headArrays = new ArrayList<ZDT_007_ReqRecordsHead>();        headArrays.add(head);        String jsonString = JSON.toJSONString(headArrays);        ifPostback.setPostbackContent(jsonString);        ifPostback.setPostbackResult(BackResultEnum.DEFAULT_STATE.getCode());        ifPostback.setCreateTime(new Date());        ifPostback.setCreateUser(loginName);        ifPostback.setDestSystem(OtherSystemEnum.SYSYTEM_SAP.getEnumName());        return ifPostback;    }    private void createT05AndT06Items(List<TransferDtl> transferDtlList, Integer fmWhs, Integer toWhs, ZDT_007_ReqRecordsHead head, List<ZDT_007_ReqRecordsHeadItems> items) {        for (TransferDtl transferDtl : transferDtlList) {            Long transferDtlId = transferDtl.getTransferDtlId();            List<TransferDtlGoods> transferDtlGoodsList = transferDtlGoodsService.selectByDtlId(transferDtlId);            //根据DTL_GOODS下面的QA_STATUS分组传，            Map<Integer, List<TransferDtlGoods>> qaStatusMap = transferDtlGoodsList.stream().collect(Collectors.groupingBy(s -> s.getQaStatus()));            for (Map.Entry<Integer, List<TransferDtlGoods>> entry : qaStatusMap.entrySet()) {                Integer keyQa = entry.getKey();//WMS_TRANSFER_DTL_GOODS:QA_STATUS                List<TransferDtlGoods> dtlGoodsList = entry.getValue();                int qty = dtlGoodsList.size();                String fmFactory = transferDtl.getFmFactory();                Integer fmQaStatus = transferDtl.getFmQaStatus();                Warehouse fmWarehouse = warehouseService.selectByPK(fmWhs);                //根据WMS的仓库CODE+factory找SAP的仓库CODE                String fmWhsCode = fmWarehouse.getWhsCode();//                    CodeMapping fmCodeMapping = codeMappingService.selectByWhsCodeAndFactory(fmFactory, fmWhsCode, fmQaStatus);                CodeMapping fmCodeMapping = codeMappingNewService.selectByWhsCodeAndFactory(fmFactory, fmWhsCode, keyQa);                if (fmCodeMapping == null) {                    String message = String.format("根据调拨单明细的仓库CODE:【%s】和工厂代码:【%s】未找SAP对应的仓库信息,请维护【内外部系统代码映射表】", fmWhsCode, fmFactory);                    Shift.fatal(StatusCode.BUSINESS_ERR, message);                }                String toFactory = transferDtl.getToFactory();                Integer toQaStatus = transferDtl.getToQaStatus();                Warehouse toWarehouse = warehouseService.selectByPK(toWhs);                //根据WMS的仓库CODE+factory找SAP的仓库CODE                String toWhsCode = toWarehouse.getWhsCode();//                CodeMapping toCodeMapping = codeMappingService.selectByWhsCodeAndFactory(toFactory, toWhsCode, toQaStatus);                CodeMapping toCodeMapping = codeMappingNewService.selectByWhsCodeAndFactory(toFactory, toWhsCode, keyQa);                if (toCodeMapping == null) {                    String message = String.format("根据调拨单明细的仓库CODE:【%s】和工厂代码:【%s】未找SAP对应的仓库信息,请维护【内外部系统代码映射表】", toWhsCode, toFactory);                    Shift.fatal(StatusCode.BUSINESS_ERR, message);                }                log.info("供应商：{}", transferDtl.getUdf5());                if (transferDtl.getUdf5() != null) {                    head.setLIFNR(transferDtl.getUdf5());//供应商 （创建类型2必填），YC说明细的FM供应商都是一样的,YC说改成取这个值                } else {                    head.setLIFNR("");//供应商 （创建类型2必填）                }                List<TransferDtlGoods> transferDtlGoods = transferDtlGoodsService.selectByDtlId(transferDtl.getTransferDtlId());//                    BigDecimal qty = transferDtlGoods.stream().filter(s -> s.getQty() != null).map(s -> s.getQty()).reduce(BigDecimal.ZERO, BigDecimal::add);                TransferDtlGoods dtlGoods = transferDtlGoods.get(0);                Goods goods = goodsService.selectBySn(dtlGoods.getGoodsSn());                ZDT_007_ReqRecordsHeadItems headItems = new ZDT_007_ReqRecordsHeadItems();                headItems.setZCGHH(transferDtl.getTransferLineNo());//调拨单行号                //特殊库存 的意思 就是库存是绑定订单的,转出转入都绑定,所以是两个e from SAP——WZP                headItems.setSOBKZ("E");//特殊库存标识（转出）                headItems.setUMSOK("E");//特殊库存标识（转入）                if (transferDtl.getToSoNo() == null) {                    headItems.setKDAUF("");//订单号码（转出）                } else {                    headItems.setKDAUF(transferDtl.getToSoNo());//订单号码（转出）                }                headItems.setKDPOS(transferDtl.getFmSoLineNo());//订单行项目（转出）                if (transferDtl.getFmSoNo() == null) {                    headItems.setMAT_KDAUF("");//订单号码（转入）                } else {                    headItems.setMAT_KDAUF(transferDtl.getFmSoNo());//订单号码（转入）                }                headItems.setMAT_KDPOS(transferDtl.getToSoLineNo());//订单行项目（转入）                headItems.setWERKS(fmFactory);//工厂（转出）                headItems.setUMLGO(fmCodeMapping.getMappingCode());//库位（转出）/SAP说传他们的仓库                headItems.setUMWRK(toFactory);//工厂（转入）                headItems.setLGORT(toCodeMapping.getMappingCode());//库位（转入）/SAP说传他们的仓库                Sku sku = skuService.getSkuByPk(goods.getSkuId());                headItems.setMATNR(sku.getSkuCode());//物料号//                    headItems.setMENGE(qty.toString());//数量                headItems.setMENGE(String.valueOf(qty));//数量                headItems.setBUDAT(getDateStr());//过帐日期                ZDT_Reserve zdt_reserve = new ZDT_Reserve();                zdt_reserve.setRsv1("");                zdt_reserve.setRsv2("");                zdt_reserve.setRsv3("");                zdt_reserve.setRsv4("");                zdt_reserve.setRsv5("");                headItems.setRSV(zdt_reserve);                items.add(headItems);            }        }    }    private void createT03AndT04Items(List<TransferDtl> transferDtlList, Integer fmWhs, Integer toWhs, ZDT_007_ReqRecordsHead head, List<ZDT_007_ReqRecordsHeadItems> items) {        for (TransferDtl transferDtl : transferDtlList) {            String fmFactory = transferDtl.getFmFactory();            Integer fmQaStatus = transferDtl.getFmQaStatus();            Warehouse fmWarehouse = warehouseService.selectByPK(fmWhs);            //根据WMS的仓库CODE+factory找SAP的仓库CODE            String fmWhsCode = fmWarehouse.getWhsCode();            CodeMapping fmCodeMapping = codeMappingNewService.selectByWhsCodeAndFactory(fmFactory, fmWhsCode, fmQaStatus);            if (fmCodeMapping == null) {                String message = String.format("根据调拨单明细的仓库CODE:【%s】和工厂代码:【%s】未找SAP对应的仓库信息,请维护【内外部系统代码映射表】", fmWhsCode, fmFactory);                Shift.fatal(StatusCode.BUSINESS_ERR, message);            }            String toFactory = transferDtl.getToFactory();            Integer toQaStatus = transferDtl.getToQaStatus();            Warehouse toWarehouse = warehouseService.selectByPK(toWhs);            //根据WMS的仓库CODE+factory找SAP的仓库CODE            String toWhsCode = toWarehouse.getWhsCode();            CodeMapping toCodeMapping = codeMappingNewService.selectByWhsCodeAndFactory(toFactory, toWhsCode, toQaStatus);            if (toCodeMapping == null) {                String message = String.format("根据调拨单明细的仓库CODE:【%s】和工厂代码:【%s】未找SAP对应的仓库信息,请维护【内外部系统代码映射表】", toWhsCode, toFactory);                Shift.fatal(StatusCode.BUSINESS_ERR, message);            }//            if (transferDtl.getFmVendor() != null) {            log.info("供应商：{}", transferDtl.getUdf5());            log.info("供应商：{}", transferDtl.getUdf5());            log.info("供应商：{}", transferDtl.getUdf5());            if (transferDtl.getUdf5() != null) {//                head.setLIFNR(transferDtl.getFmVendor().toString());//供应商 （创建类型2必填），YC说明细的FM供应商都是一样的                head.setLIFNR(transferDtl.getUdf5());//供应商 （创建类型2必填），YC说明细的FM供应商都是一样的,YC说改成取这个值            } else {                head.setLIFNR("");//供应商 （创建类型2必填）            }            List<TransferDtlGoods> transferDtlGoods = transferDtlGoodsService.selectByDtlId(transferDtl.getTransferDtlId());            BigDecimal qty = transferDtlGoods.stream().filter(s -> s.getQty() != null).map(s -> s.getQty()).reduce(BigDecimal.ZERO, BigDecimal::add);            TransferDtlGoods dtlGoods = transferDtlGoods.get(0);            Goods goods = goodsService.selectBySn(dtlGoods.getGoodsSn());            ZDT_007_ReqRecordsHeadItems headItems = new ZDT_007_ReqRecordsHeadItems();            headItems.setZCGHH(transferDtl.getTransferLineNo());//调拨单行号            //特殊库存 的意思 就是库存是绑定订单的,转出转入都绑定,所以是两个e from SAP——WZP            headItems.setSOBKZ("E");//特殊库存标识（转出）            headItems.setUMSOK("E");//特殊库存标识（转入）//            headItems.setKDAUF(transferDtl.getFmSoNo());//订单号码（转出）            if (transferDtl.getToSoNo() == null) {                headItems.setKDAUF("");//订单号码（转出）            } else {                headItems.setKDAUF(transferDtl.getToSoNo());//订单号码（转出）            }            headItems.setKDPOS(transferDtl.getFmSoLineNo());//订单行项目（转出）//            headItems.setMAT_KDAUF(transferDtl.getToSoNo());//订单号码（转入）            if (transferDtl.getFmSoNo() == null) {                headItems.setMAT_KDAUF("");//订单号码（转入）            } else {                headItems.setMAT_KDAUF(transferDtl.getFmSoNo());//订单号码（转入）            }            headItems.setMAT_KDPOS(transferDtl.getToSoLineNo());//订单行项目（转入）            headItems.setWERKS(fmFactory);//工厂（转出）            headItems.setUMLGO(fmCodeMapping.getMappingCode());//库位（转出）/SAP说传他们的仓库            headItems.setUMWRK(toFactory);//工厂（转入）            headItems.setLGORT(toCodeMapping.getMappingCode());//库位（转入）/SAP说传他们的仓库            Sku sku = skuService.getSkuByPk(goods.getSkuId());            headItems.setMATNR(sku.getSkuCode());//物料号//            headItems.setMENGE(goods.getQty().toString());//数量            headItems.setMENGE(qty.toString());//数量            headItems.setBUDAT(getDateStr());//过帐日期            ZDT_Reserve zdt_reserve = new ZDT_Reserve();            zdt_reserve.setRsv1("");            zdt_reserve.setRsv2("");            zdt_reserve.setRsv3("");            zdt_reserve.setRsv4("");            zdt_reserve.setRsv5("");            headItems.setRSV(zdt_reserve);            items.add(headItems);        }    }    /**     * 获得当前年月日     *     * @return     */    public String getDateStr() {        Date now = new Date();        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");        String dateStr = formatter.format(now);        return dateStr;    }    /**     * 获得当前时间时分秒     *     * @return     */    private String getTimeStr() {        Date now = new Date();        SimpleDateFormat formatter = new SimpleDateFormat("HHmmss");        String timeStr = formatter.format(now);        return timeStr;    }    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)    public Result removePicktaskPda(CancelPicktaskRequest cancelPicktaskRequest, HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws Exception {        String loginName = HttpSessionUtil.getLoginName(servletRequest);        List<CancelPicktaskDtlRequest> cancelPicktaskDtlRequestList = cancelPicktaskRequest.getCancelPicktaskDtlRequestList();        List<String> goodsSnList = cancelPicktaskDtlRequestList.stream().map(s -> s.getGoodsSn()).collect(Collectors.toList());        //写goods的操作日志        //先查原来的状态        List<Goods> goodsList = goodsService.selectListByListSn(goodsSnList);        int waitDowmCode = GoodsStatusEnum.WAIT_DOWM.getCode();//已下架        //1）更新产品SN状态 = 已下架(4)        Integer row = goodsService.updateStatusByGoodsList(waitDowmCode, goodsSnList, loginName);        //写goods的操作日志        //先查原来的状态        List<Goods> goodsNewList = goodsService.selectListByListSn(goodsSnList);        for (Goods goods : goodsList) {            for (Goods goodsNew : goodsNewList) {                if (goods.getGoodsSn().equals(goodsNew.getGoodsSn())) {                    //                    GoodsLog goodsLog = new GoodsLog();                    goodsLog.setOpCode(GoodsLogEnum.UN_PICK.getCode());                    goodsLog.setReason(GoodsLogEnum.UN_PICK.getDescription());                    goodsLog.setGoodsSn(goods.getGoodsSn());                    goodsLog.setOperator(loginName);                    goodsLog.setCreateUser(loginName);                    goodsLog.setCreateTime(new Date());                    Goods goodsCopy = new Goods();                    goodsCopy.setGoodsId(goodsNew.getGoodsId());                    goodsCopy.setModifyUser(goodsNew.getModifyUser());                    goodsCopy.setModifyTime(goodsNew.getModifyTime());                    goodsCopy.setStatus(goodsNew.getStatus());                    String updateContent = new String();                    String goodsJson = JSON.toJSONString(goods);                    String goodsCopyJson = JSON.toJSONString(goodsCopy);                    updateContent = "未更新的:" + goodsJson + ",更新后的:" + goodsCopyJson;                    goodsLog.setUpdateContent(updateContent);                    int insertRow = goodsLogMapper.insert(goodsLog);                }            }        }        //从拣货任务明细货品清单(WMS_PICKTASK_DTL_GOODS)中删除对应的SN信息        Integer deleteRow = picktaskDtlGoodsService.deleteBySnList(goodsSnList);        log.info("删除{}条记录", deleteRow);        Map<String, List<CancelPicktaskDtlRequest>> map = cancelPicktaskDtlRequestList.stream().collect(Collectors.groupingBy(s -> s.getGoodsSn()));        for (Map.Entry<String, List<CancelPicktaskDtlRequest>> entry : map.entrySet()) {            CancelPicktaskDtlRequest cancelPicktaskDtlRequest = entry.getValue().get(0);            Goods goods = goodsService.selectBySn(cancelPicktaskDtlRequest.getGoodsSn());            //更新库位【分配数】            InvLoc invLoc = invLocService.selectByGoods(goods);            UpdateInventoryInputDto updateLocInventory = new UpdateInventoryInputDto();            BeanUtils.copyProperties(invLoc, updateLocInventory);            updateLocInventory.setAlocQty(goods.getQty().negate());            updateLocInventory.setQty(BigDecimal.ZERO);            updateLocInventory.setHoldQty(BigDecimal.ZERO);            updateLocInventory.setPreAlocQty(BigDecimal.ZERO);            updateLocInventory.setPreOutQty(BigDecimal.ZERO);            updateLocInventory.setPreInQty(BigDecimal.ZERO);            updateLocInventory.setOperator(loginName);            updateLocInventory.setLotNo(invLoc.getLotno());//            Integer updateLocInventroy = inventoryService.updateLocInventroy(updateLocInventory);//            inventoryService.invQtyValidation(updateLocInventory, 0);            inventoryService.updateLocInventroy(updateLocInventory);            //更新库区【分配数】            LocationResponse location = locationService.getLocation(goods.getLocId());            Integer zoneId = null;            if (location != null) {                zoneId = location.getZoneId();//库区ID            }            InvZone invZone = invZoneService.getEffectiveInvLoc(goods, zoneId);            UpdateInventoryInputDto updateZoneInventory = new UpdateInventoryInputDto();            BeanUtils.copyProperties(invZone, updateZoneInventory);            updateZoneInventory.setAlocQty(goods.getQty().negate());            updateZoneInventory.setQty(BigDecimal.ZERO);            updateZoneInventory.setHoldQty(BigDecimal.ZERO);            updateZoneInventory.setPreAlocQty(BigDecimal.ZERO);            updateZoneInventory.setPreOutQty(BigDecimal.ZERO);            updateZoneInventory.setPreInQty(BigDecimal.ZERO);            updateZoneInventory.setOperator(loginName);            updateZoneInventory.setLotNo(invZone.getLotno());//            Integer updateZoneInventoryRow = inventoryService.updateZoneInventory(updateZoneInventory);//            inventoryService.invQtyValidation(updateZoneInventory, 1);            inventoryService.updateZoneInventory(updateZoneInventory);            //①拣货任务明细表(WMS_PICKTASK_DTL)实际拣货数(CMP_QTY)减少；对应的发货单明细(WMS_GDN_DTL)拣货数量(PICK_QTY)减少。            PicktaskDtl picktaskDtl = picktaskDtlService.selectByPicktaskDtlId(cancelPicktaskDtlRequest.getDtlId());            //拣货任务明细表            BigDecimal cmpQty = picktaskDtl.getCmpQty();            PicktaskDtl picktaskDtlUpdate = new PicktaskDtl();            picktaskDtlUpdate.setPicktaskDtlId(cancelPicktaskDtlRequest.getDtlId());            picktaskDtlUpdate.setCmpQty(cmpQty.subtract(goods.getQty()));            picktaskDtlUpdate.setModifyTime(new Date());            picktaskDtlUpdate.setModifyUser(loginName);            Integer rowUpdate = picktaskDtlService.updateCmpQtyByPk(picktaskDtlUpdate);            log.info("成功更新{}条记录", rowUpdate);            //发货单明细            GdnDtl gdnDtl = gdnCoreService.getGdnDtlByGdnDtlId(picktaskDtl.getDocDtlId());            BigDecimal pickQty = gdnDtl.getPickQty();            GdnDtl gdnDtlUpdate = new GdnDtl();            gdnDtlUpdate.setGdnDtlId(gdnDtl.getGdnDtlId());            gdnDtlUpdate.setPickQty(pickQty.subtract(goods.getQty()));            Integer gdnDtlUpdateRow = gdnCoreService.updateGdnDtlPickQty(gdnDtlUpdate.getGdnDtlId(), gdnDtlUpdate.getPickQty(), loginName);            log.info("成功更新{}条记录", gdnDtlUpdateRow);            //②对应的发货单明细(WMS_GDN_DTL)，若发货数量(ship_qty)=0并且拣货数量(PICK_QTY)<订单数量(ORDER_QTY) 时，状态(STATUS)更新为 拣货中(4)            //若发货数量(ship_qty)=0并且拣货数量(PICK_QTY)=0 时，状态(STATUS)更新为 待拣货(3)            //发货数量(ship_qty)=0            boolean flagShip = gdnDtl.getShipQty().compareTo(BigDecimal.ZERO) == 0;            //拣货数量(PICK_QTY)<订单数量(ORDER_QTY)            boolean flagSub = gdnDtlUpdate.getPickQty().compareTo(gdnDtl.getOrderQty()) == -1;            if (flagShip && flagSub) {                GdnDtl gdnDtlStatus = new GdnDtl();                gdnDtlStatus.setGdnDtlId(gdnDtl.getGdnDtlId());                gdnDtlStatus.setStatus(GdnDtlStatusEnum.PICKING.getCode());                gdnDtlStatus.setModifyUser(loginName);                gdnDtlStatus.setModifyTime(new Date());                log.info("发货明细:{}", gdnDtlStatus.toString());                Integer gdnDtlStatusRow = gdnCoreService.updateGdnDtlStatusByPk(gdnDtlStatus.getGdnDtlId(), gdnDtlStatus.getStatus(), gdnDtlStatus.getModifyUser(), gdnDtlStatus.getModifyTime());                log.info("成功更新{}条记录", gdnDtlStatusRow);            }            //拣货数量(PICK_QTY)=0            boolean flagZero = gdnDtlUpdate.getPickQty().compareTo(BigDecimal.ZERO) == 0;            if (flagShip && flagZero) {                GdnDtl gdnDtlStatus = new GdnDtl();                gdnDtlStatus.setGdnDtlId(gdnDtl.getGdnDtlId());                gdnDtlStatus.setStatus(GdnDtlStatusEnum.WAITPICK.getCode());                gdnDtlStatus.setModifyUser(loginName);                gdnDtlStatus.setModifyTime(new Date());                log.info("发货明细:{}", gdnDtlStatus.toString());                Integer gdnDtlStatusRow = gdnCoreService.updateGdnDtlStatusByPk(gdnDtlStatus.getGdnDtlId(), gdnDtlStatus.getStatus(), gdnDtlStatus.getModifyUser(), gdnDtlStatus.getModifyTime());                log.info("成功更新{}条记录", gdnDtlStatusRow);            }        }        Map<Integer, List<CancelPicktaskDtlRequest>> dtlIdMap = cancelPicktaskDtlRequestList.stream().collect(Collectors.groupingBy(s -> s.getDtlId()));        for (Map.Entry<Integer, List<CancelPicktaskDtlRequest>> entry : dtlIdMap.entrySet()) {            Integer key = entry.getKey();//DTL_ID            //③拣货任务明细表(WMS_PICKTASK_DTL)：            //a.若已拣货数量(CMP_QTY)=0，则更新状态=未拣货(1)；            //b.若已拣货数量(CMP_QTY)>0并且<计划数量(PLAN_QTY)，则更新状态=拣货中(2)；            //c.若【取消拣货任务】开关为开启状态，则调用【取消拣货任务】服务(见1.2[拣货任务管理]2.4.2节)，更新状态=取消(0)；//            PicktaskDtl picktaskDtlCmp = picktaskDtlService.selectByPicktaskDtlId(cancelPicktaskDtlRequest.getDtlId());            PicktaskDtl picktaskDtlCmp = picktaskDtlService.selectByPicktaskDtlId(key);            boolean cmpZeroFlag = picktaskDtlCmp.getCmpQty().compareTo(BigDecimal.ZERO) == 0;            boolean cmpOneFlag = picktaskDtlCmp.getCmpQty().compareTo(BigDecimal.ZERO) == 1;            boolean dtlPlanFlag = picktaskDtlCmp.getCmpQty().compareTo(picktaskDtlCmp.getPlanQty()) == -1;            if (cmpZeroFlag) {                int noPickCode = PicktaskStatusEnum.NO_PICK.getCode();//                picktaskDtlService.updateStatusByPk(cancelPicktaskDtlRequest.getDtlId(), noPickCode, loginName, new Date());                picktaskDtlService.updateStatusByPk(key, noPickCode, loginName, new Date());            }            if (cmpOneFlag && dtlPlanFlag) {                int pickIngCode = PicktaskStatusEnum.PICK_ING.getCode();//拣货中//                picktaskDtlService.updateStatusByPk(cancelPicktaskDtlRequest.getDtlId(), pickIngCode, loginName, new Date());                picktaskDtlService.updateStatusByPk(key, pickIngCode, loginName, new Date());            }            if (cancelPicktaskRequest.getCancelPicktaskFlag()) {                List<Integer> picktaskDtlList = new ArrayList<>();//                picktaskDtlList.add(cancelPicktaskDtlRequest.getDtlId());                picktaskDtlList.add(key);                picktaskService.cancelPick(picktaskDtlList, servletRequest);            }        }        //④拣货任务主表(WMS_PICKTASK_HEADER)：        //若一张拣货任务下全部拣货任务明细状态(STATUS) =未拣货(1)，更新拣货任务主表的状态(STATUS) =未拣货(1)，否则更新拣货任务表头的状态=拣货中(2)；        List<Integer> dtlIdList = cancelPicktaskDtlRequestList.stream().map(s -> s.getDtlId()).distinct().collect(Collectors.toList());        List<PicktaskDtl> picktaskDtlList = picktaskDtlService.selectByPicktaskDtlIdList(dtlIdList);        List<Integer> headerIdList = picktaskDtlList.stream().map(s -> s.getPicktaskHeaderId()).distinct().collect(Collectors.toList());        List<PicktaskHeader> picktaskHeaderList = picktaskHeaderService.selectByHeadIdList(headerIdList);        int noPickCode = PicktaskStatusEnum.NO_PICK.getCode();        int pickIngCode = PicktaskStatusEnum.PICK_ING.getCode();        int cancelCode = PicktaskStatusEnum.CANCEL.getCode();        for (PicktaskHeader picktaskHeader : picktaskHeaderList) {            List<PicktaskDtl> picktaskDtls = picktaskDtlService.getDtlByHeadId(picktaskHeader.getPicktaskHeaderId());            int picktaskDtlListSize = picktaskDtls.size();            //同一单头下所有明细的状态为【未拣货】的数量            Long countNoPick = picktaskDtls.stream().filter(s -> s.getStatus().equals(noPickCode)).count();            //同一单头下所有明细的状态为【取消】的数量            Long countCancel = picktaskDtls.stream().filter(s -> s.getStatus().equals(cancelCode)).count();            if (countNoPick.intValue() == picktaskDtlListSize) {                Integer rowUpdate = picktaskHeaderService.updateStatusByPK(picktaskHeader.getPicktaskHeaderId(), noPickCode, loginName, new Date());                log.info("成功更新{}条记录,{}的拣货单头状态为:{}", rowUpdate, picktaskHeader.getPicktaskNo(), noPickCode);            } else if(countCancel.intValue() == picktaskDtlListSize){                Integer rowUpdate = picktaskHeaderService.updateStatusByPK(picktaskHeader.getPicktaskHeaderId(), cancelCode, loginName, new Date());                log.info("成功更新{}条记录,{}的拣货单头状态为:{}", rowUpdate, picktaskHeader.getPicktaskNo(), cancelCode);            } else {                Integer rowUpdate = picktaskHeaderService.updateStatusByPK(picktaskHeader.getPicktaskHeaderId(), pickIngCode, loginName, new Date());                log.info("成功更新{}条记录,{}的拣货单头状态为:{}", rowUpdate, picktaskHeader.getPicktaskNo(), pickIngCode);            }        }        //TODO 测试代码，测试和投产记得删除//        int a = 0 / 0;        return new Result();    }}